/**
 * @file sims_core.cpp
 * @author lrc
 * @brief
 * @version 0.1
 * @date 2023-01-01
 *
 * @copyright Copyright (c) 2023
 *
 */
#include "sims_core.h"

#include <fstream>
#include <iostream>
#include <algorithm>
#include <sstream>

/**
 * @brief 重载+运算符
 *
 * @param a
 * @param b
 * @return float
 */
float operator+(const float &a, const CourseStructDef &b)
{
    return a + b.score * b.weight;
}

/**
 * @brief 计算学生总成绩
 */
void StudentsClassDef::set_totalScore()
{
    totalScore = 0;
    for (auto &c : coursescores)
    {
        totalScore = totalScore + *c;
    }
}

/**
 * @brief 计算学生排名
 * @param _stuList
 */
void StudentsClassDef::set_rank(StudentListType *_stuList)
{
    rank = 1;
    for (auto &s : *_stuList)
    {
        if (totalScore < s->totalScore)
            rank++;
    }
}

/**
 * @brief 计算优良等级
 * @param studentsNum
 */
void StudentsClassDef::set_level(float studentsNum)
{
    if (rank == -1)
        return;

    float temp = rank / studentsNum;
    if (temp > 0.8)
        level = "E";
    else if (0.6 <= temp && temp < 0.8)
        level = "D";
    else if (0.4 <= temp && temp < 0.6)
        level = "C";
    else if (0.2 <= temp && temp < 0.4)
        level = "B";
    else
        level = "A";
}

/**
 * @brief 获取课程成绩
 *
 * @param name
 * @return float
 */
float StudentsClassDef::get_courseScore(string name)
{
    for (auto c : coursescores)
    {
        if (name == c->name)
        {
            return c->score;
        }
    }
    return 0;
}

/**
 * @brief 添加课程成绩
 *
 * @param _course
 * @param _weight
 * @param _score
 */
void StudentsClassDef::add_course(string _course, float _score, float _weight)
{
    CourseStructDef *course = new CourseStructDef(_course, _weight, _score);
    coursescores.push_back(course);
}

/**
 * @brief 设置课程权重
 *
 * @param course
 * @param weight
 */
void StudentsClassDef::set_courseWeight(string _course, float _weight)
{
    for (auto &c : coursescores)
    {
        if (_course == c->name)
            c->weight = _weight;
    }
}

/**
 * @brief 设置课程成绩
 *
 * @param _course
 * @param _score
 */
void StudentsClassDef::set_courseScore(string _course, float _score)
{
    for (auto &c : coursescores)
    {
        if (c->name == _course)
            c->score = _score;
    }
}

/**
 * @brief 获取课程平均分
 *
 * @param _course
 * @param _studentList
 * @return float
 */
float get_courseAverage(string _course, StudentListType &_studentList)
{
    float average = 0;
    for (auto student : _studentList)
        average += student->get_courseScore(_course);
    average /= _studentList.size();
    return average;
}

/**
 * @brief 根据学生属性设置学生参数
 * @param parameter
 * @param value
 */
void StudentsClassDef::set_Parameter(std::string parameter, std::string value, StudentListType *_stuList)
{
    if (parameter == "姓名")
        name = value;
    else if (parameter == "学号")
        ID = value;
    else if (parameter == "学院")
        academy = value;
    else if (parameter == "年级")
        grade = value;
    else if (parameter == "专业")
        major = value;
    else
    {
        // 字符串转数字
        std::istringstream istr1(value);
        float _score;
        istr1 >> _score;
        // 增加课程
        add_course(parameter, _score);
    }
}

/**
 * @brief 获得学生某个属性值
 * @param parameter 属性名称
 * @return
 */
template <typename T>
T StudentsClassDef::get_Parameter(std::string parameter)
{
    if (parameter == "姓名")
        return name;
    else if (parameter == "学号")
        return ID;
    else if (parameter == "学院")
        return academy;
    else if (parameter == "年级")
        return grade;
    else if (parameter == "专业")
        return major;
    else if (parameter == "总分")
        return totalScore;
    else if (parameter == "排名")
        return rank;
    else if (parameter == "优良等级")
        return level;
    else
        return get_courseScore(parameter);
}

/**
 * @brief 计算科目及格率
 * @param stuList 统计的学生列表
 * @param course  课程名
 * @return
 */
float get_PassRate(StudentListType *stuList, string course)
{
    int sum = 0;
    for (auto &s : *stuList)
    {
        if (s->get_courseScore(course) >= 60)
            sum++;
    }
    return (float)sum / (float)stuList->size();
}

/**
 * @brief 计算科目分数层占比
 * @param stuList 统计的学生列表
 * @param course 课程名
 * @param down 分数层下界
 * @param up   分数层上届
 * @return
 */
float get_ScoreRate(StudentListType *stuList, string course, float down, float up)
{
    int sum = 0;
    for (auto &s : *stuList)
    {
        if (down <= s->get_courseScore(course) && s->get_courseScore(course) < up)
            sum++;
    }
    return (float)sum / (float)stuList->size();
}
